Before a computing device may accomplish a desired task, it must receive an appropriate set of instructions. Executed by a device's processor(s), these instructions direct the operation of the device. These instructions can be stored in a memory of the computer. Instructions can invoke other instructions.
A computing device, such as a server, router, desktop computer, laptop, etc., and other devices having processor logic and memory, includes an operating system layer and an application layer to enable the device to perform various functions or roles. The operating system layer includes a “kernel”, i.e., master control program, that runs the computing device. The kernel provides task management, device management, and data management, among others. The kernel sets the standards for application programs that run on the computing device and controls resources used by application programs. The application layer includes programs, i.e., executable instructions, which are located above the operating system layer and accessible by a user. As used herein, “user space”, “user-mode”, or “application space” implies a layer of code which is less privileged and more directly accessible by users than the layer of code which is in the operating system layer or “kernel” space.
When the execution of the program instructions call for data or other program instructions, the program will want to know where in memory the data or instructions are stored. In effect, the program will use a means for referencing or indexing where in memory the data or instructions are held. The kernel is responsible for virtual memory management. With virtual memory, a process is assigned its own virtual address space, which may not be available to other processes. In virtual memory a process has a logical view of memory that does not correspond to the actual layout of physical memory. When a process uses a virtual memory address the virtual memory system translates it into a physical address using a virtual to physical address mapping contained in some type of look up structure and address mapping database. Virtual memory is a technique within the memory management subsystem to allow the processor to access a larger memory space than the actual physical memory that exists in the processor system of a computing device. With many programs running on a computing device available physical memory space would quickly become an issue if all of the programs were to be assigned a physical memory address.
In an operating system, a process refers to a running program with input, output, and a state. For example, a process includes the current values of the program counter, the registers, and the variables of an executing program. Each process has an “address space”. Further each process includes one or more threads associated with the “address space”. The thread is sometimes referred to as a lightweight process. Processes and threads are well known in the art and are described, for example, in Modern Operating Systems, Andrew S. Tannenbaum, (1992). Hence, running a process generally requires executing a thread and accessing the address space.
A memory stack is a region of reserved memory in which programs store status data such as procedure and function call return addresses, passed parameters, local variables, and program instructions, i.e., program stacks. In certain processor architectures fixed regions of memory are protected and fully allocated to a process rather than a fixed region received and various portions allocated over time. Additionally, some processor architectures consist of two distinct program stacks per process execution context. Certain programming environments, however, export the notion of a single program stack. As a result, an operating system may have to allocate the two distinct program stacks within a single memory allocation provided by an application. The two stacks may be based at opposite ends of the allocation and grow towards each other as the application makes nested function or procedure calls. In the instance where two stacks collide, memory corruption and/or indeterminate program behavior may occur. If a guard page is used in a fixed manner, one stack may run into the guard page long before the other stack and waste memory space and/or abort a program prematurely.